package com.tianji.learning.listener;

import com.tianji.api.client.course.CourseClient;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.exceptions.BizIllegalException;
import com.tianji.common.utils.JsonUtils;
import com.tianji.common.utils.StringUtils;
import com.tianji.learning.domain.po.LearningLesson;
import com.tianji.learning.domain.po.LearningRecord;
import com.tianji.learning.enums.LessonStatus;
import com.tianji.learning.service.ILearningLessonService;
import com.tianji.learning.service.ILearningRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Objects;

@Slf4j
@Component
public class LearningRecordSyncToMysqlListener {


    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private ILearningRecordService recordService;
    @Autowired
    private ILearningLessonService lessonService;
    @Autowired
    private CourseClient courseClient;

    @RabbitListener(
            bindings = @QueueBinding(
                    value=@Queue(MqConstants.Queue.LEARNING_RECORD_QUEUE),
                    exchange = @Exchange(value = MqConstants.Exchange.LEARNING_DELAY_EXCHANGE, type = ExchangeTypes.DIRECT, delayed = "true"),
                    key =MqConstants.Key.LEARNING_RECORD_KEY
            )
    )
    public void onLearningRecordSyncToMysql(LearningRecord recordMsg){
        log.info("视频-收到了延迟消息，进度：{}, 是否第一次超过50%：{}", recordMsg.getMoment(), recordMsg.getFirstFinish());
        // 获取redis中最新的数据
        String key = recordService.getLearningRecordKey(recordMsg.getLessonId(), recordMsg.getSectionId(), recordMsg.getUserId());
        String json = redisTemplate.opsForValue().get(key);
        if(StringUtils.isEmpty(json)){
            log.error("缓存的学习记录不存在，key：{}",key);
            return;
        }
        LearningRecord recordRedis = JsonUtils.toBean(json, LearningRecord.class);
        // 说明是第一次到达50%，不管是否在观看
        if(recordRedis.getFirstFinish()){
            log.info("视频-第一次超过50%，更新学习记录，进度：{},finished:{}, finishTime:{}", recordRedis.getMoment(),recordRedis.getFinished(),recordRedis.getFinishTime());
            // 更新学习记录：Moment、FinishTime、Finished
            recordService.updateById(recordRedis);
            // 更新课表，LatestLearnTime、LatestSectionId、LearnedSections、status
            LearningLesson lesson = lessonService.getById(recordRedis.getLessonId());
            Integer oldNum = lesson.getLearnedSections();
            lesson.setLearnedSections(oldNum+1);
            // feign，查询课程的总的小节数量
            CourseFullInfoDTO course = courseClient.getCourseInfoById(lesson.getCourseId(), false, false);
            if(course == null){
                log.error("根据courseid：{}查询不到course信息", lesson.getCourseId());
                throw new BizIllegalException("网络异常");
            }
            Integer totalSectionNum = course.getSectionNum();
            // 如果学完所有的章节，更新课表的状态为已经学完
            if(oldNum + 1 >= totalSectionNum){
                lesson.setStatus(LessonStatus.FINISHED.getValue());
            }
            lesson.setUpdateTime(LocalDateTime.now());
            lesson.setLatestLearnTime(LocalDateTime.now());
            lesson.setLatestSectionId(recordRedis.getSectionId());
            lessonService.updateById(lesson);
            log.info("视频-第一次超过50%，更新课表， 已学习的小节数量：{}, 状态：{}", lesson.getLearnedSections(),lesson.getStatus());
            return;
        }
        // 拿到消息中的进度
        Integer msgMoment = recordMsg.getMoment();
        // 拿到redis中最新的进度
        Integer redisMoment = recordRedis.getMoment();
        // 如果二者是不一致的，说明用户还在看，不用任何处理
        if(!Objects.equals(msgMoment, redisMoment)){
            log.info("视频持续播放中，key：{},进度：{}", key, recordRedis.getMoment());
        }else{
            log.info("视频已经退出播放，key：{}, 更新播放记录和课表，进度：{}", key, recordRedis.getMoment());
            // 如果不一致，说明用户已经退出了播放，redis中的数据-》写入到mysql
            // 更新播放记录
            recordService.updateById(recordRedis);
            // 2. 更新课表：LatestLearnTime、LatestSectionId
            // 查询lesson
            LearningLesson lesson = lessonService.getById(recordRedis.getLessonId());
            //  课表：最近学习的小节和最近学习的时间
            lesson.setUpdateTime(LocalDateTime.now());
            lesson.setLatestLearnTime(LocalDateTime.now());
            lesson.setLatestSectionId(recordRedis.getSectionId());
            lessonService.updateById(lesson);
        }
    }
}